#ifndef CKERNEL_H
#define CKERNEL_H

#include <QObject>
#include <huiyimainwindow.h>
#include<huiyidialog.h>
#include "TcpClientMediator.h"
#include <QDebug>
#include "packdef.h"
#include "logindialog.h"
#include"md5.h"
#include<QMessageBox>
#include"roomdialog.h"
#include <QTime>

#include "audioread.h"
#include "audiowrite.h"
#include "videoread.h"
#include "screenread.h"

//多线程发送视频的类
class CsendVideoWorker;
//多线程发送音频的类
class CsendAudioWorker;

//协议映射表使用的类型
class Ckernel;
typedef void (Ckernel::*PFUN)(uint sock,char* buf,int nlen);

class Ckernel : public QObject
{
    Q_OBJECT
public:
    explicit Ckernel(QObject *parent = 0);

    //单例
    static Ckernel* getInstance()
    {
        static Ckernel kernel;
        return &kernel;
    }

signals:
    void SIG_sendAudio(char* buf,int nlen);//多线程发送音频
    void SIG_sendVideo(char* buf,int nlen);//多线程发送视频

public slots:
    //设置协议映射关系
    void setNetPackMap();
    //初始化配置
    void initConfig();
    void slot_destroy();
    //网络信息处理
    void slot_dealData(uint sock,char* buf,int nlen);
    //发送登录信息
    void slot_loginCommit(QString tel,QString pass);
    //发送注册信息
    void slot_registerCommit(QString tel,QString pass,QString name);
    //登录回复
    void slot_dealLoginRs(uint sock,char* buf,int nlen);
    //注册回复
    void slot_dealRegisterRs(uint sock,char* buf,int nlen);
    //创建房间请求
    void slot_createRoom();
    //进入房间请求
    void slot_joinRoom();
    //创建房间回复
    void slot_dealCreateRoomRs(uint sock,char* buf,int nlen);
    //进入房间回复
    void slot_dealJoinRoomRs(uint sock,char* buf,int nlen);
    //加入成员处理
    void slot_dealRoomMemberRs(uint sock,char* buf,int nlen);
    //关闭会议窗口，退出会议
    void slot_quitroom();
    //离开房间请求处理
    void slot_dealLeaveRq(uint sock,char* buf,int nlen);

    void slot_audioPause();//暂停音频采集
    void slot_audioStart();//开始音频采集
    void slot_audioFrame(QByteArray ba);//发送音频帧

    void slot_videoPause();//暂停视频采集
    void slot_videoStart();//开始视频采集
    void slot_refreshVideo(int id,QImage& img);//刷新图片显示

    void slot_screenPause();//暂停桌面采集
    void slot_screenStart();//开始桌面采集

    //音频帧的处理
    void slot_dealAudioFrameRq(uint sock,char* buf,int nlen);
    //视频帧的处理
    void slot_dealVideoFrameRq(uint sock,char* buf,int nlen);
    //发送视频帧
    void slot_sendVideoFrame(QImage img);

    //多线程发送音频
    void slot_SendAudio(char* buf,int nlen);
    //多线程发送视频
    void slot_SendVideo(char *buf, int nlen);

private:
    huiyiDialog* m_pHuiyiDlg;
    INetMediator* m_pClient;
    LoginDialog* m_pLoginDlg;
    roomDialog* m_pRoomDlg;

    //协议映射表
    PFUN m_netPackMap[_DEF_PACK_COUNT];
    //服务器的ip
    QString m_serverIP;

    int m_id;//自己的id
    int m_roomid;//所在房间的id
    QString m_name;

    ////////////
    ///音频 一个采集，多个播放，每一个房间成员使用一个1:1的map映射
    AudioRead * m_pAudioRead;
    std::map<int,AudioWrite*> m_mapIdToAudioWrite;

    QSharedPointer<CsendAudioWorker> m_pSendAudioWorker;
    ////////////
    ///视频采集
    videoRead* m_pVideoRead;
    ScreenRead* m_pScreenRead;

    QSharedPointer<CsendVideoWorker> m_pSendVideoWorker;

    enum client_type{audio_client = 0,video_client = 1};
    INetMediator* m_pAVclient[2];
};

#include"threadworker.h"
class CsendAudioWorker:public ThreadWorker
{
    Q_OBJECT
public slots:
    void slot_sendAudio(char* buf,int nlen)
    {
        Ckernel::getInstance()->slot_SendAudio(buf,nlen);
    }
};

class CsendVideoWorker:public ThreadWorker
{
    Q_OBJECT
public slots:
    void slot_sendVideo(char *buf, int nlen)
    {
        Ckernel::getInstance()->slot_SendVideo(buf,nlen);
    }
};

#endif // CKERNEL_H
